#include <iostream>

using namespace std;

template <class T>
class varray
{
public:
    // 无参构造
    varray() : start(nullptr), finish(nullptr), end_of_storage(nullptr) {}
    // 带长度的有参构造
    varray(int n) { create(n); }
    // 带长度和默认值的有参构造
    varray(int n, T value) { create(n, value); }
    // 复制构造
    varray(varray<T> &p);
    // 返回头指针
    T *begin() { return start; }
    // 返回指向最后一个值下一位的指针
    T *end() { return finish; }
    // 返回元素个数
    int size() { return finish - start; }
    // 返回容量
    int capacity() { return end_of_storage - start; }
    // 判断是否为空
    bool empty() { return start == finish; }
    // 在最后添加元素
    void push_back(T value);
    // 移除最后元素
    void pop_back() { --finish; }
    // 在指定位置添加元素
    void insert(T *t, T value);
    // 移除指定位置元素
    void erase(T *t);
    // 移除指定位置多个元素
    void erase(T *t1, T *t2);
    // 清空元素
    void clear() { erase(begin(), end()); }
    // 返回第一个元素
    T &front() { return *start; }
    // 返回最后一个元素
    T &back() { return *(finish - 1); }
    // 重载[]运算符
    T &operator[](int n) { return *(start + n); }
    // 析构函数
    ~varray() { delete[] start; }

protected:
    T *start;
    T *finish;
    T *end_of_storage;

protected:
    void create(int n);
    void create(int n, const T &value);
};

template <class T>
void varray<T>::insert(T *t, T value)
{
    if (capacity() == 0)
    {
        cout << "insert 0:" << endl;
        start = new T[2];
        finish = start;
        end_of_storage = start + 2;
    }

    if (finish != end_of_storage)
    {
        cout << "insert =:" << endl;
        for (auto i = end(); i != t; i--)
            *i = *(i - 1);
        *t = value;
        finish++;
    }
    else
    {
        int i;
        int cap = capacity();
        T *tmp = new T[2 * cap];
        for (i = 0; begin() + i != t; i++)
            *(tmp + i) = *(begin() + i);
        *(tmp + i) = value;
        for (auto j = 0; t + j != end(); j++)
            *(tmp + i + 1 + j) = *(t + j);
        swap(start, tmp);
        finish = start + cap + 1;
        end_of_storage = start + 2 * cap;
        delete[] tmp;
    }
}

template <class T>
void varray<T>::erase(T *t)
{
    if (t == end())
        return;
    for (auto i = t + 1; i != end(); i++)
        *(i - 1) = *i;
    finish--;
}

template <class T>
void varray<T>::erase(T *t1, T *t2)
{
    for (auto i = 0; t2 + i != end(); i++)
        *(t1 + i) = *(t2 + i);
    finish = finish - (t2 - t1);
}

template <class T>
void varray<T>::push_back(T value)
{
    if (capacity() == 0)
    {
        start = new T[2];
        finish = start;
        end_of_storage = start + 2;
    }

    if (finish != end_of_storage)
    {
        *finish = value;
        finish++;
    }
    else
    {
        int cap = capacity();
        T *tmp = new T[2 * cap];
        for (auto i = 0; i < size(); i++)
            *(tmp + i) = *(start + i);
        *(tmp + size()) = value;
        swap(start, tmp);
        finish = start + cap + 1;
        end_of_storage = start + 2 * cap;
        delete[] tmp;
    }
}

template <class T>
varray<T>::varray(varray<T> &p)
{
    create(p.size());
    for (auto i = 0; i < p.size(); i++)
        *(start + i) = *(p.begin() + i);
}

template <class T>
void varray<T>::create(int n)
{
    start = new T[n];
    finish = start + n;
    end_of_storage = finish;
}

template <class T>
void varray<T>::create(int n, const T &value)
{
    start = new T[n];
    for (int i = 0; i < n; i++)
        *(start + i) = value;
    finish = start + n;
    end_of_storage = finish;
}

template <class T>
void print(varray<T> &array)
{
    cout << "size:" << array.size() << "    capacity:" << array.capacity() << endl;
    for (auto i = array.begin(); i != array.end(); i++)
        cout << *i << " ";
    cout << endl;
}

int main()
{
    varray<int> array;
    array.push_back(10);
    array.push_back(20);
    cout << "尾部添加元素输出:" << endl;
    print(array);
    array.insert(array.begin(), 5);
    cout << "插入元素后输出(容量已增加):" << endl;
    print(array);
    array.push_back(30);
    array.push_back(40);
    cout << "尾部插入元素后输出(容量已增加):" << endl;
    print(array);
    cout << "删除指定位置元素输出:" << endl;
    array.erase(array.begin());
    print(array);
    cout << "尾部删除元素输出:" << endl;
    array.pop_back();
    print(array);
    array.clear();
    cout << "清空数组后输出:" << endl;
    print(array);
    cout << "数组是否为空:";
    cout << array.empty() << endl;
    return 0;
}